/*
* Copyright© 2018 Shanxi Lu'an Taihang Laihui Net Tech co.,LTD.
*/
package com.laihuichuxing.netty.server.server.module.lbs.driver;

import com.google.protobuf.InvalidProtocolBufferException;
import com.laihuichuxing.netty.common.constant.TopicConstant;
import com.laihuichuxing.netty.common.core.session.Session;
import com.laihuichuxing.netty.common.core.session.SessionManager;
import com.laihuichuxing.netty.common.mq.dto.DriverListenDto;
import com.laihuichuxing.netty.common.mq.dto.DriverPositionDto;
import com.laihuichuxing.netty.common.mq.dto.DriverStrokeDto;
import com.laihuichuxing.netty.common.mq.dto.PassengerPositionDto;
import com.laihuichuxing.netty.common.mq.producer.PositionProducer;
import com.laihuichuxing.netty.server.server.module.Common;
import com.laihuichuxing.netty.server.server.module.lbs.dao.LbsDao;
import com.laihuichuxing.netty.server.server.module.login.entity.Login;
import com.laihuichuxing.protobuf.module.DriverModule;
import com.laihuichuxing.protobuf.module.LbsModule;
import com.laihuichuxing.protobuf.module.OrderModule;
import com.laihuichuxing.socket.LbsCmd;
import com.laihuichuxing.socket.ModuleId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * Description: 司机定位
 *
 * @author YangGuang
 * @since: 1.0
 * Create Date Time: 2018/10/9 9:24
 * Update Date Time:
 */
@Component
public class DriverPositionHandlerImpl implements DriverPositionHandler {

    private Logger logger = LoggerFactory.getLogger(DriverPositionHandlerImpl.class);

    @Autowired
    private PositionProducer positionProducer;

    @Autowired
    private TopicConstant topicConstant;

    @Autowired
    private LbsDao lbsDao;

    @Override
    public void listenPosition(Session session, byte[] data) {
        try {
            // 反序列化,获取客户端发来的数据
            LbsModule.DriverPosition driverPosition = LbsModule.DriverPosition.parseFrom(data);
            // 获取当前用户会话
            Object object = session.getAttachment();
            if (object != null) {
                Login login = (Login) object;
                // 如果不是null,放入mq
                putPositionMQ(login, driverPosition, topicConstant.getListenPosition());
            }
        } catch (InvalidProtocolBufferException e) {
            logger.error("司机开启听单后实时定位protocol异常:{}", e.toString(), e);
        } catch (Exception e) {
            logger.error("司机开启听单后实时定位异常:{}", e.toString(), e);
        }
    }

    @Override
    public void driverArrival(Session session, byte[] data) {
        try {
            // 反序列化,获取客户端发来的数据
            LbsModule.DriverPosition driverPosition = LbsModule.DriverPosition.parseFrom(data);
            // 获取当前用户会话
            Object object = session.getAttachment();
            if (object != null) {
                Login login = (Login) object;
                // 如果不是null,放入mq
                putPositionMQ(login, driverPosition, topicConstant.getDriverArrival());
                // 给客户端回消息
                Common.lbsNotifyClient(session,LbsCmd.DRIVER_ARRIVAL);
            }
        } catch (InvalidProtocolBufferException e) {
            logger.error("司机确认到达定位protocol异常:{}", e.toString(), e);
        } catch (Exception e) {
            logger.error("司机确认到达定位异常:{}", e.toString(), e);
        }
    }

    @Override
    public void driverOrder(Session session, byte[] data) {
        try {
            // 反序列化,获取客户端发来的数据
            OrderModule.Order order = OrderModule.Order.parseFrom(data);
            // 判断司机是否在线
            String driverMobile = order.getDriverMobile();
            boolean online = SessionManager.isOnline(driverMobile);
            if (online) {
                String passengerMobile = order.getPassengerMobile();
                // 给司机发消息
                SessionManager.sendMessage(driverMobile, ModuleId.LBS, LbsCmd.DRIVER_ORDER, order);
                TimeUnit.SECONDS.sleep(1);
                // 给乘客发消息
                SessionManager.sendMessage(passengerMobile, ModuleId.LBS, LbsCmd.DRIVER_ORDER, order);
                // 给客户端回消息
                Common.lbsNotifyClient(session,LbsCmd.DRIVER_ORDER);
            } else {
                // 重新派单
                this.reOrder(order);
            }
        } catch (Exception e) {
            logger.error("派单成功protocol异常:{}", e.toString(), e);
        }
    }

    /**
     * Description: 重新派单
     * @param order order
     * @author YangGuang
     * Create Date Time: 2018/11/1 17:39
     * Update Date Time:
     */
    private void reOrder(OrderModule.Order order) {
        // 回滚订单状态
        lbsDao.updateOrderStatus(order.getOrderId());
        // 回滚司机状态
        lbsDao.updateDriverStatus(order.getDriverMobile());
        // 查询订单
        PassengerPositionDto passengerPositionDto = lbsDao.selectById(order.getOrderId());
        passengerPositionDto.setMobile(order.getPassengerMobile());
        positionProducer.position(passengerPositionDto,topicConstant.getPassengerOrder());
    }

    @Override
    public void driverListen(Session session, byte[] data) {
        try {
            // 反序列化,获取客户端发来的数据
            DriverModule.DriverListen driverListen = DriverModule.DriverListen.parseFrom(data);
            // 放入mq
            this.putDriverListenMQ(driverListen);
            // 给客户端回消息
            Common.lbsNotifyClient(session,LbsCmd.DRIVER_LISTEN);
        } catch (InvalidProtocolBufferException e) {
            logger.error("司机开启听单protocol异常:{}", e.toString(), e);
        }  catch (Exception e) {
            logger.error("司机开启听单异常:{}", e.toString(), e);
        }
    }

    @Override
    public void driverDeparture(Session session, byte[] data) {
        try {
            // 反序列化数据
            LbsModule.DriverOrderLbs driverOrderLbs = LbsModule.DriverOrderLbs.parseFrom(data);
            // 获取当前用户会话
            Object object = session.getAttachment();
            if (object != null) {
                Login login = (Login) object;
                // 如果不是null,放入mq
                this.putStrokeMQ(login, driverOrderLbs, topicConstant.getDriverDeparture());
                // 给客户端回消息
                Common.lbsNotifyClient(session,LbsCmd.DRIVER_DEPARTURE);
            }
        } catch (InvalidProtocolBufferException e) {
            logger.error("司机发车反序列化异常:{}", e.toString(), e);
        }
    }

    @Override
    public void driverTake(Session session, byte[] data) {
        try {
            // 反序列化,获取客户端发来的数据
            LbsModule.DriverPosition driverPosition = LbsModule.DriverPosition.parseFrom(data);
            // 获取当前用户会话
            Object object = session.getAttachment();
            if (object != null) {
                Login login = (Login) object;
                // 如果不是null,放入mq
                putPositionMQ(login, driverPosition, topicConstant.getDriverTake());
                // 给客户端回消息
                Common.lbsNotifyClient(session,LbsCmd.DRIVER_TAKE);
            }
        } catch (InvalidProtocolBufferException e) {
            logger.error("司机接到乘客反序列化异常:{}", e.toString(), e);
        } catch (Exception e) {
            logger.error("司机接到乘客异常:{}", e.toString(), e);
        }
    }

    @Override
    public void driverNotifyPassenger(Session session, byte[] data) {
        try {
            // 反序列化,获取客户端发来的数据
            LbsModule.DriverMeetPosition driverMeetPosition = LbsModule.DriverMeetPosition.parseFrom(data);
            // 获取当前用户会话
            Object object = session.getAttachment();
            if (object != null) {
                SessionManager.sendMessage(driverMeetPosition.getPassengerMobile(), ModuleId.LBS, LbsCmd.PASSENGER_RECEIVE_DRIVER, driverMeetPosition);
            }
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
    }

    /**
     * Description: 行程信息放入mq
     *
     * @param login          当前登录用户
     * @param driverOrderLbs 司机行程信息
     * @param topic          mq主题
     * @author YangGuang
     * Create Date Time: 2018/10/17 18:03
     * Update Date Time:
     */
    private void putStrokeMQ(Login login, LbsModule.DriverOrderLbs driverOrderLbs, String topic) {
        DriverStrokeDto driverStrokeDto = new DriverStrokeDto();
        driverStrokeDto.setCityCode(driverOrderLbs.getCityCode());
        driverStrokeDto.setOrderId(driverOrderLbs.getOrderId());
        driverStrokeDto.setLatitude(driverOrderLbs.getLatitude());
        driverStrokeDto.setLongitude(driverOrderLbs.getLongitude());
        driverStrokeDto.setMobile(login.getMobile());
        positionProducer.position(driverStrokeDto, topic);
    }

    /**
     * Description:  定位信息放入mq
     *
     * @param login          当前登录用户
     * @param driverPosition 司机定位信息
     * @param topic          mq主题
     * @author YangGuang
     * Create Date Time: 2018/10/9 10:02
     * Update Date Time:
     */
    private void putPositionMQ(Login login, LbsModule.DriverPosition driverPosition, String topic)  {
        DriverPositionDto driverPositionDto = new DriverPositionDto();
        driverPositionDto.setLongitude(driverPosition.getLongitude());
        driverPositionDto.setLatitude(driverPosition.getLatitude());
        driverPositionDto.setCityCode(driverPosition.getCityCode());
        driverPositionDto.setMobile(login.getMobile());
        positionProducer.position(driverPositionDto, topic);
    }

    /**
     * Description:  定位信息放入mq
     *
     * @param driverListen 司机听单信息
     * @author YangGuang
     * Create Date Time: 2018/10/9 10:02
     * Update Date Time:
     */
    private void putDriverListenMQ(DriverModule.DriverListen driverListen) {
        DriverListenDto driverListenDto = new DriverListenDto();
        driverListenDto.setToken(driverListen.getToken());
        driverListenDto.setCityCode(driverListen.getCityCode());
        positionProducer.position(driverListenDto, topicConstant.getDriverResource());
    }

}
